package com.zimi.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zimi.mapper.SysDutyMapper;
import com.zimi.mapper.SysDutyPrivilegeMapper;
import com.zimi.model.SysDuty;
import com.zimi.model.SysDutyPrivilege;
import com.zimi.model.SysUser;
import com.zimi.util.UserUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * 单位职务表 Service
 *
 * @author lnintr
 * @since 2019-05-22
 */
@Service
public class SysDutyService {

    @Autowired
    private SysDutyMapper sysDutyMapper;

    @Autowired
    private SysDutyPrivilegeMapper sysDutyPrivilegeMapper;

    public Object list() {
        return sysDutyMapper.selectList(new QueryWrapper<SysDuty>().lambda().eq(SysDuty::getDutyState, 1).orderByAsc(SysDuty::getDutySort));
    }

    public Object pageList(SysDuty duty, int page, int limit) {
        return duty.selectPage(new Page<>(page, limit), new QueryWrapper<SysDuty>().setEntity(duty).lambda().orderByAsc(SysDuty::getDutySort));
    }

    @Transactional
    public Object insert(SysDuty duty) {
        SysUser user = UserUtil.getUser();
        duty.setDutyState(1);
        duty.setDutySort(sysDutyMapper.selectSort());
        duty.setCreateUser(user.getId());
        duty.setCreateTime(new Date());

        Object result = duty.insert();

        return result;
    }

    @Transactional
    public Object update(SysDuty sysDuty) {
        // 1）对要修改的对象加行锁
        SysDuty result = sysDuty.selectOne(new QueryWrapper<SysDuty>().lambda().eq(SysDuty::getId, sysDuty.getId()).last("for update"));

        // 2）判断该数据已经被改过没有
        if (result.getUpdateTime() != null) {
            if (sysDuty.getUpdateTime() == null) {
                throw new RuntimeException("修改数据失败，数据已经被其他用户改过。");
            } else {
                if (sysDuty.getUpdateTime().getTime() != result.getUpdateTime().getTime()) {
                    throw new RuntimeException("修改数据失败，数据已经被其他用户改过。");
                }
            }
        }

        SysUser user = UserUtil.getUser();

        result.setDutyName(sysDuty.getDutyName());
        result.setDutyRemark(sysDuty.getDutyRemark());
        result.setUpdateUser(user.getId());
        result.setUpdateTime(new Date());

        // 3)变更数据
        return result.updateById();
    }

    @Transactional
    public SysDuty delete(SysDuty duty) {
        // 1）对要修改的对象加行锁
        SysDuty result = duty.selectOne(new QueryWrapper<SysDuty>().lambda().eq(SysDuty::getId, duty.getId()).last("for update"));

        // 2）判断该数据已经被改过没有
        if (result.getUpdateTime() != null) {
            if (duty.getUpdateTime() == null) {
                throw new RuntimeException("删除数据失败，数据已经被其他用户改过。");
            } else {
                if (duty.getUpdateTime().getTime() != result.getUpdateTime().getTime()) {
                    throw new RuntimeException("删除数据失败，数据已经被其他用户改过。");
                }
            }
        }

        SysUser user = UserUtil.getUser();

        Date updateTime = new Date();

        result.setDutyState(2);
        result.setUpdateUser(user.getId());
        result.setUpdateTime(updateTime);

        // 3)变更数据
        result.updateById();

        SysDutyPrivilege sysDutyPrivilege = new SysDutyPrivilege().setUpdateUser(user.getId()).setUpdateTime(updateTime).setPrivilegeState(2);
        sysDutyPrivilegeMapper.update(sysDutyPrivilege, new UpdateWrapper<SysDutyPrivilege>().lambda().eq(SysDutyPrivilege::getDutyId, result.getId()).eq(SysDutyPrivilege::getPrivilegeState, 1));

        return result;
    }

    @Transactional
    public String moveUp(SysDuty duty) {
        int sort = duty.getDutySort();
        List<SysDuty> list = sysDutyMapper.moveUp(sort);

        if (list != null) {
            SysDuty duty1 = list.get(list.size() - 1);
            int id1 = duty1.getId();

            duty.setDutySort(duty1.getDutySort());
            duty.updateById();

            duty1.setDutySort(sort);
            duty1.updateById();
            return "上移成功！";
        } else {
            return "已经移动到最顶端！";
        }

    }

    @Transactional
    public int move(List<SysDuty> sysDutyList) {
        Map<Integer, SysDuty> cateMap = new HashMap<>();
        // 1）对要修改的对象数据数量进行验证
        if (sysDutyList.size() != 2) {
            throw new RuntimeException("提交的关于交换顺序的数据不正确。");
        }

        // 2）对要修改的对象加行锁
        List<Integer> idList = new ArrayList<>();
        for (SysDuty sd : sysDutyList) {
            cateMap.put(sd.getId(), sd);
            idList.add(sd.getId());
        }

        List<SysDuty> result = sysDutyMapper.selectList(new QueryWrapper<SysDuty>().lambda().in(SysDuty::getId, idList).last("for update"));

        if (result == null || result.size() != 2) {
            throw new RuntimeException("服务器关于交换顺序的数据异常。");
        }

        SysDuty tmpDuty = null;

        SysUser user = UserUtil.getUser();
        Date updateTime = new Date();

        for (SysDuty sd : sysDutyList) {
            tmpDuty = cateMap.get(sd.getId());

            // 3）判断该数据已经被改过没有
            if (sd.getUpdateTime() != null) {
                if (tmpDuty.getUpdateTime() == null) {
                    throw new RuntimeException("删除数据失败，数据已经被其他用户改过。");
                } else {
                    if (sd.getUpdateTime().getTime() != tmpDuty.getUpdateTime().getTime()) {
                        throw new RuntimeException("删除数据失败，数据已经被其他用户改过。");
                    }
                }
            }

            // 4)变更数据
            tmpDuty.setUpdateUser(user.getId());
            tmpDuty.setUpdateTime(updateTime);
            tmpDuty.updateById();
        }

        return 0;
    }

    @Transactional
    public int recycle(List<SysDuty> sysDutyList) {
        Map<Integer, SysDuty> dutyMap = new HashMap<>();
        // 2）对要修改的对象加行锁
        List<Integer> idList = new ArrayList<>();
        for (SysDuty sd : sysDutyList) {
            dutyMap.put(sd.getId(), sd);
            idList.add(sd.getId());
        }

        List<SysDuty> result = sysDutyMapper.selectList(new QueryWrapper<SysDuty>().lambda().in(SysDuty::getId, idList).last("for update"));

        if (result != null && result.size() > 0) {
            SysDuty tmpDuty = null;

            SysUser user = UserUtil.getUser();
            Date updateTime = new Date();

            for (SysDuty sd : result) {
                tmpDuty = dutyMap.get(sd.getId());

                // 3）判断该数据已经被改过没有
                if (sd.getUpdateTime() != null) {
                    if (tmpDuty.getUpdateTime() == null) {
                        throw new RuntimeException("删除数据失败，数据已经被其他用户改过。");
                    } else {
                        if (sd.getUpdateTime().getTime() != tmpDuty.getUpdateTime().getTime()) {
                            throw new RuntimeException("删除数据失败，数据已经被其他用户改过。");
                        }
                    }
                }
            }

            SysDuty sysDuty = new SysDuty().setUpdateUser(user.getId()).setUpdateTime(updateTime).setDutyState(1);
            sysDutyMapper.update(sysDuty, new UpdateWrapper<SysDuty>().lambda().in(SysDuty::getId, idList));
        } else {
            throw new RuntimeException("删除数据失败，数据已经被其他用户改过。");
        }

        return 0;
    }

    //根据id查询
    public Object selectById(int id) {
        return sysDutyMapper.selectById(id);
    }
}
